package com.ecnu.system.service.impl;

import com.ecnu.common.constant.HttpStatus;
import com.ecnu.common.core.domain.AjaxResult;
import com.ecnu.common.core.domain.entity.SysUser;
import com.ecnu.common.core.domain.model.LoginUser;
import com.ecnu.common.core.redis.RedisCache;
import com.ecnu.common.exception.ServiceException;
import com.ecnu.common.utils.DateUtils;
import com.ecnu.common.utils.OtherUtil;
import com.ecnu.common.utils.SecurityUtils;
import com.ecnu.common.utils.StringUtils;
import com.ecnu.system.domain.Project;
import com.ecnu.system.domain.ProjectUser;
import com.ecnu.system.domain.SysEmail;
import com.ecnu.system.domain.dto.SmtpEmailDTO;
import com.ecnu.system.domain.dto.UpdatePwdDTO;
import com.ecnu.system.domain.vo.ProjectByUserVO;
import com.ecnu.system.mapper.SysEmailMapper;
import com.ecnu.system.service.IEmailService;
import com.ecnu.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class EmailServiceImpl implements IEmailService {
    @Autowired
    private RedisTemplate<String, String> template;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysEmailMapper emailMapper;
    @Autowired
    private RedisCache redisCache;
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 发送验证码
     *
     * @param email
     * @return
     */
    @Override
    public AjaxResult sendCode(String email) throws UnsupportedEncodingException {
        if (StringUtils.isNotBlank(template.opsForValue().get(email))
                &&
                template.getExpire(email, TimeUnit.SECONDS) > 240) {
            throw new RuntimeException("验证码已发送，请勿重复请求");
        }
        SysUser sysUser = new SysUser();
        sysUser.setEmail(email);
        List<SysUser> sysUsers = userService.selectUserListForPwd(sysUser);
        if (sysUsers.size() == 0) {
            return AjaxResult.error("我们未找到与此邮箱关联的账户，请检查邮箱或进行注册");
        }

        String code = OtherUtil.generateCode(6); // 生成6位验证码
//        Map<String, String> map = OtherUtil.sendVerificationCode(email, code);

        List<String> toEmails = new ArrayList<>();
        toEmails.add(email);
        String 主题 = "密码重置验证码-AI智慧学习中心";
        String 内容 = "<p>    尊敬的用户:您好! <br> 您的验证码是：</p>" +
                "<p style=\"background-color: #f0f0f0; " +
                "box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 15px; " +
                "display: inline-block; font-size: 20px; font-weight: bold; " +
                "letter-spacing: 2px;\">" + code + "</p>" +
                "<p> 请妥善保管。(有效期为 5 分钟)；</p>" +
                "<p>若非本人操作，请忽略本邮件，造成困扰向您致歉。<p>"+
                "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a> </p><p>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";;
        //发邮件
        sendEmail(toEmails, 主题, 内容);

        //写入redis
        template.delete(email);
        template.opsForValue().set(email, code);//添加键值对
        template.expire(email, 5, TimeUnit.MINUTES);//设定过期时间
        return AjaxResult.success("验证码已发送到邮箱：" + email+
                "\n验证码发送成功。如果没有收到，请检查垃圾邮件。");

    }

    /**
     * 验证验证码
     *
     * @param email
     * @param inputCode
     * @return
     */
    @Override
    public Boolean verifyCode(String email, String inputCode) {
        String code = template.opsForValue().get(email);
        if (inputCode != null && inputCode.equals(code)) {
            template.delete(email);// 删除redis中的验证码
            return true;
        }
        return false;
    }

    /**
     * 审核邮件
     *
     * @return
     */
    @Override
    public Boolean ReviewEmail(Project project, LoginUser loginUser) {//获取收件人信息
        List<String> toEmails = new ArrayList<>();
        List<SysUser> sysUsers=new ArrayList<>();
        if (project.getIsRange().equals("3")) {
            SysUser sysUser = new SysUser();
            sysUser.setRoleId(2L);
            sysUsers = userService.selectUserByRoleList(sysUser);
        }else if (project.getIsRange().equals("2")) {
            SysUser sysUser = new SysUser();
            sysUser.setRoleId(103L);
            sysUsers = userService.selectUserByRoleList(sysUser);
            long deptId = loginUser.getDeptId();
            sysUsers = sysUsers.stream().filter(sysUser1 -> sysUser1.getDeptId().equals(deptId)).collect(Collectors.toList());

        }
        if (sysUsers.size()==0) {
            return true;
        }
        sysUsers.forEach(a->{
            if (!StringUtils.isBlank(a.getEmail())) {
                toEmails.add(a.getEmail());
            }
        });
        //?"All":String.valueOf(loginUser.getDeptId())
        String 主题 = "【" + project.getProName() + "】活动提请调整可见范围的申请通知";
        String 内容 = "<p>管理员,您好！</p>" +
                "<p>  " + loginUser.getUser().getNickName() + "教师在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>" +
                "）中创建【" + project.getProName() +
                "】活动，申请" + (project.getIsRange().equals("3") ? "平台可见" : "机构可见") + "，请按需审核放行。 </p>\n" +
                "<p>  谢谢！</p>\n\n" +
                "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        return sendEmail(toEmails, 主题, 内容);
//   return true;
    }

    @Override
    public Boolean ReviewCompletedEmail(Project project, String reviewStatus) {
        List<String> toEmails = new ArrayList<>();
        String createUser = project.getCreateUser();
        SysUser sysUser = userService.selectUserById(Long.valueOf(createUser));
        if (StringUtils.isBlank(sysUser.getEmail())) {
            throw new ServiceException("审核完成，由于用户邮箱为空，无法发送邮件",HttpStatus.ACCEPTED);
        }
        toEmails.add(sysUser.getEmail());
        String 主题 = "";
        String 内容 = "";
        if (reviewStatus.equals("1")) {
            主题 = "【" + project.getProName() + "】活动提请调整可见范围的审核状态通知";
            内容 = "<p>"+sysUser.getNickName() + "老师，您好！</p>\n" +
                    "<p>  您先前在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>）中创建【" + project.getProName() +
                    "】 活动，申请 " + (project.getIsRange().equals("3") ? "平台可见" : "机构可见") + "，管理员已审核放行。</p>\n" +
                    "<p>  需要提醒的是，本活动已面向其他用户或互联网开放，请严格遵循国家相关法律法规，开展系列教研实践活动、不做其他用途；如发现异常，视情节严重，我们将主动提请上诉权利、追究相关法律责任。</p>\n" +
                    "<p>  谢谢！</p>\n\n" +
                    "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        } else {
            主题 = "【" + project.getProName() + "】活动提请调整可见范围的审核状态通知";
            内容 = "<p>"+sysUser.getNickName() + "老师，您好！</p>\n" +
                    "<p>  您先前在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>）中创建【" + project.getProName() +
                    "】 活动，申请 " + (project.getIsRange().equals("3") ? "平台可见" : "机构可见") + "，管理员已审阅、但不予放行。</p>\n" +
                    "<p>  请及时登录平台进入个人中心的【审核与提交】查阅原因。更新信息后，重新提交。</p>\n" +
                    "<p>  谢谢！</p>\n\n" +
                    "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        }
        return sendEmail(toEmails, 主题, 内容);
    }

    @Override
    public Boolean ReviewJoinCompletedEmail(ProjectByUserVO one, LoginUser loginUser, String status) {//活动参与人，登录人
        List<String> toEmails = new ArrayList<>();
        SysUser sysUser = userService.selectUserById(Long.valueOf(one.getUserId()));
        if (StringUtils.isBlank(sysUser.getEmail())) {
            throw new ServiceException("审核完成，由于用户邮箱为空，暂时无法发送邮件通知", HttpStatus.ACCEPTED);
        }
        //?"All":String.valueOf(loginUser.getDeptId())
        toEmails.add(sysUser.getEmail());
        String 主题 = "";
        String 内容 = "";
        if (status.equals("0")) {
            主题 = "【" + one.getName() + "】 活动报名审核成功通知";
            内容 = "<p>"+sysUser.getNickName() + ",您好!</p>" +
                    "<p>  您先前在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>）中参与【" + one.getName() + "】 活动的报名" +
                    "，已通过审核，请参照活动官方页面中的事项安排，有序参与活动。</p>\n" +
                    "<p>  谢谢！</p>\n\n" +
                    "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        } else {
            主题 = "【" + one.getName() + "】 活动报名审核不通过通知";
            内容 = "<p>"+sysUser.getNickName() + ",您好!</p>\n" +
                    "<p>  您先前在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>）中参与【" + one.getName() + "】 活动的报名" +
                    "，未通过审核。请及时登录平台进入个人中心的【审核与提交】查阅原因。更新信息后，重新提交。</p>\n" +
                    "<p>  谢谢！</p>\n" +
                    "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        }
        return sendEmail(toEmails, 主题, 内容);
//        return true;
    }

    @Override
    public Boolean ReviewJoinEmail(Project one, ProjectUser user, SysUser sysUser) {//活动，报名人，活动老师
        List<String> toEmails = new ArrayList<>();

        if (StringUtils.isBlank(sysUser.getEmail())) {
            throw new ServiceException("申请已提交，由于用户邮箱为空，暂时无法发送邮件通知", HttpStatus.ACCEPTED);
        }

        toEmails.add(user.getEmail());
        String 主题 = "【" + one.getProName() + "】活动报名回执";
        String 内容 ="<p>"+ user.getUserName() + "，您好！</p>" +
                "<p>  我们已收到您在AI智慧学习中心（" + "<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>" + "）参与【" + one.getProName() + "】活动的报名信息，正在按序审核，静待后续消息。</p>" +
                "<p>  谢谢！</p>" +
                "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        return sendEmail(toEmails, 主题, 内容);
    }

    @Override
    public Boolean General(List<SysUser> users,Project project) {
        List<String> toEmails = new ArrayList<>();
        users.forEach(a -> {
            if (!StringUtils.isBlank(a.getEmail())) {
                String 主题 = "消息提醒-AI智慧学习中心";
                String 内容 ="<p>"+ a.getNickName() + "，您好！</p>\n" +
                        "<p>  您在AI智慧学习中心（<a href=\"https://ba.ecnu.edu.cn\">https://ba.ecnu.edu.cn</a>）中参与或创建的【" + project.getProName() + "】活动有更新，劳您登录平台查阅处理。</p>\n" +
                        "<p>  谢谢！</p>\n\n" +
                        "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
                sendEmail(toEmails, 主题, 内容);
            }
        });
        return true;
    }

    @Override
    public SysEmail smtpCode() {
        SysEmail smtpCode = redisCache.getCacheObject("smtp_code");
        if (smtpCode != null) {
            return smtpCode;
        }
        List<SysEmail> sysEmails = emailMapper.selectList(null);
        if (sysEmails.size() == 0) {
            return null;
        }
        redisCache.setCacheObject("smtp_code", sysEmails.get(0), 1, TimeUnit.DAYS);
        return sysEmails.get(0);
    }

    @Override
    public AjaxResult smtpCodeEdit(SmtpEmailDTO dto) {
        SysEmail sysEmail = new SysEmail();
        BeanUtils.copyProperties(dto, sysEmail);
        sysEmail.setFromAddress(dto.getSmtpUsername());
        int delete = emailMapper.delete(null);
        int insert = emailMapper.insert(sysEmail);
        if (insert > 0) {
            if (redisCache.hasKey("smtp_code")) {
                redisCache.deleteObject("smtp_code");
            }
            redisCache.setCacheObject("smtp_code", sysEmail, 1, TimeUnit.DAYS);
            return AjaxResult.success("编辑成功");
        }
        return AjaxResult.success("编辑失败");
    }

    @Override
    public void GeneralEmail(String 标题, String 正文, SysUser loginUser) {
        List<String> toEmails = new ArrayList<>();
        toEmails.add(loginUser.getEmail());
        String 主题 = 标题;
        String 内容 = 正文 +
                "<p> 谢谢！</p>\n\n" +
                "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a> </p><p>  " + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";
        sendEmail(toEmails, 主题, 内容);
    }

    @Override
    public AjaxResult updatePwd(UpdatePwdDTO dto) {
        SysUser sysUser = new SysUser();
        sysUser.setEmail(dto.getEmail());
        List<SysUser> sysUsers = userService.selectUserListForPwd(sysUser);
        if (sysUsers.size() == 0) {
            return AjaxResult.error("邮箱不存在，请联系管理员处理");
        }
        Boolean aBoolean = verifyCode(dto.getEmail(), dto.getCode());
        if (!aBoolean) {
            return AjaxResult.error("验证码错误，请重新获取");
        }
        sysUser = sysUsers.get(0);
        String newPwd = OtherUtil.generateCodeLength(8);

//        if (SecurityUtils.matchesPassword(newPwd, sysUser.getPassword()))
////        {
////            return AjaxResult.error("新密码不能与旧密码相同");
////        }
        String newPassword = SecurityUtils.encryptPassword(newPwd);
        if (userService.resetUserPwd(sysUser.getUserName(), newPassword) > 0)
        {
            // 写邮件
            List<String> toEmails = new ArrayList<>();
            toEmails.add(sysUser.getEmail());
            String 主题 = "临时密码启用—AI智慧学习中心";
            String 内容 = "<p>    尊敬的用户 "+sysUser.getNickName()+" :您好!<br> " +
                    "登录账号为："+sysUser.getUserName()+
                    "<br>您的8位临时密码是：</p>" +
                    "<p style=\"background-color: #f0f0f0; " +
                    "box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 15px; " +
                    "display: inline-block; font-size: 20px; font-weight: bold; " +
                    "letter-spacing: 2px;\">" + newPwd + "</p>" +
                    "<p> 请尽快登录平台（https://ba.ecnu.edu.cn）个人中心修改密码，以防造成您账户损失。 </p>"+
                    "<p><a href='https://ba.ecnu.edu.cn/'>商业分析上海市级实验教学示范中心</a> </p><p>  "
                    + DateUtils.dateToString(new Date(), DateUtils.中文)+"</p>";;
            //发邮件
            sendEmail(toEmails, 主题, 内容);

            return AjaxResult.success("提交成功，临时密码已发送至您邮箱中，登录之后尽快修改密码，谢谢!");
        }
        return AjaxResult.error("修改密码异常，请联系管理员");
    }

    public String getUrl() {
//        HttpServletRequest request = ServletUtils.getRequest();
//        return getDomain(request);
        return null;
    }

    public static String getDomain(HttpServletRequest request) {
        StringBuffer url = request.getRequestURL();
        String contextPath = request.getServletContext().getContextPath();
        String string = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
        string=string.replace("http://","https://");
        return string;
    }

    public Boolean sendEmail(List<String> toEmails, String 主题, String 内容) {//获取收件人信息
        //发送邮件
        try {
            //去除空字符串
            List<String> filteredEmails = toEmails.stream()
                    .filter(email -> StringUtils.isNotBlank(email))
                    .collect(Collectors.toList());
            if (filteredEmails == null || filteredEmails.size() == 0) {
                Logger logger = LoggerFactory.getLogger(OtherUtil.class);
                logger.error("邮件发送失败，具体原因为：\n 收件人邮箱为空");
                throw new ServiceException("邮件发送失败，具体原因为：\n 管理员收件人邮箱为空，联系管理员调整", HttpStatus.ACCEPTED);
            }
            /**
             * 配置1：配置在application中，调整getSession方法
             */
            // 配置邮件服务器信息
//        EmailConfig emailConfig = EmailConfigHolder.getConfig();//读取的事admin配置项中email的配置
//        // 创建会话
//        Session session = getSession(emailConfig);
            /**
             * 配置2：配置在数据库中，调整getSession方法
             */
            SysEmail sysEmail = smtpCode();
            if (sysEmail == null) {
                return false;
            }
            Session session = getSession(sysEmail);


            // 创建邮件消息
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(
                    sysEmail.getFromAddress(),
                    sysEmail.getFromName())); // 发件人邮箱
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(String.join(",", filteredEmails))); // 收件人邮箱
            message.setSubject(主题); // 邮件主题
            message.setContent(内容,"text/html;charset=UTF-8"); // 邮件内容

            // 发送邮件
            Transport.send(message);
            return true; // 发送成功
        } catch (MessagingException | UnsupportedEncodingException e) {
            logger.error("邮件发送失败，具体原因为：\n" + e.getMessage());
            throw new ServiceException("请核对收件人邮箱是否正确，多次出现该问题请联系管理员老师调整", HttpStatus.ACCEPTED);
        }
    }

    private static Session getSession(SysEmail emailConfig) {

        Properties properties = new Properties();
        properties.put("mail.smtp.host", emailConfig.getSmtpHost()); // 替换为你的SMTP服务器地址
        properties.put("mail.smtp.port", emailConfig.getSmtpPort());
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.ssl.protocols", "TLSv1.2");
        properties.put("mail.smtp.ssl.enable", "true");
        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                        emailConfig.getSmtpUsername(),
                        emailConfig.getSmtpPassword()); // 替换为你的邮箱和密码
            }
        });
        return session;
    }

}
